package com.agh.portal.web.security;

import java.util.Arrays;
import java.util.Date;

import javax.persistence.TypedQuery;
import javax.validation.Valid;

import org.joda.time.format.DateTimeFormat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import com.agh.portal.domain.Student;
import com.agh.portal.domain.enumeration.Gender;
import com.agh.portal.domain.enumeration.StudentStatus;
import com.agh.portal.domain.security.User;
import com.agh.portal.service.SecurityUtils;
import com.agh.portal.service.StudentService;

@RequestMapping("/signup")
@Controller
public class SignUpController {

	@Autowired
	private PasswordEncoder passwordEncoder;

	@Autowired
	private transient MailSender mailSender;
	
	@Autowired SecurityUtils securityUtils;
	
	@Autowired StudentService studentService;

	@Autowired
	@Qualifier("accountActivationMailTemplate")
	private SimpleMailMessage mailTemplate;

	@RequestMapping(method = RequestMethod.GET)
	public String createSignUpForm(Model uiModel) {
		populateEditForm(uiModel, new SignUpForm());
		return "signup/form";
	}

	@RequestMapping(method = RequestMethod.POST)
	public String submitSignUpForm(
			@Valid @ModelAttribute("form") SignUpForm form,
			BindingResult bindingResult, Model uiModel) {

		validateMore(form, bindingResult);

		if (!bindingResult.hasErrors()) {
			User user = securityUtils.createUserAcc(form.getEmailAddress(), form.getPassword());		
			studentService.createStudent(form.getName(), form.getSurname(), form.getEmailAddress());
			String activationKey = createActivationKey(user);
			sendActivationMail(activationKey, user);

			return "redirect:/signup/registerConfirm";
		}

		populateEditForm(uiModel, form);
		return "signup/form";
	}

	private void validateMore(SignUpForm form, BindingResult bindingResult) {
		if (form.getPassword() != null && !form.getPassword().equals(form.getRetypePassword())) {
			bindingResult.rejectValue("password", "field_password_mismatch");
		}
		if(form.getEmailAddress() != null && !User.findUsersByEmailAddress(form.getEmailAddress()).getResultList().isEmpty()){
			System.out.println("hello there");
			bindingResult.rejectValue("emailAddress", "user_already_exists");
		}
	}

	@RequestMapping(params = "k", method = RequestMethod.GET)
	public String activateUser(
			@RequestParam(value = "k", required = true) String activationKey,
			@RequestParam(value = "e", required = true) String emailAddress,
			Model uiModel) {
		TypedQuery<User> query = User.findUsersByEmailAddress(emailAddress);

		try {
			User user = query.getSingleResult();

			if (createActivationKey(user).equals(activationKey)) {
				user.setActivationDate(new Date());
				user.setEnabled(true);
				user.merge();
				return "redirect:/login";
			}

		} catch (EmptyResultDataAccessException e) {
			// No such mail
		}

		return "signup/error";
	}

	@RequestMapping("/registerConfirm")
	public String thanks(Model uiModel) {
		return "signup/registerConfirm";
	}

	private void sendActivationMail(String activationKey, User user) {
		SimpleMailMessage mailMessage = new SimpleMailMessage(
				mailTemplate);
		mailMessage.setTo(user.getEmailAddress());

		Student student = Student.findStudentsByEmailAddress(user.getEmailAddress()).getResultList().get(0);
		
		mailMessage.setText(mailMessage.getText()
				.replace("{{FIRST_NAME}}", student.getName())
				.replace("{{LAST_NAME}}", student.getSurname())
				.replace("{{EMAIL_ADDRESS}}", user.getEmailAddress())
				.replace("{{ACTIVATION_KEY}}", activationKey));

		mailSender.send(mailMessage);
	}

	private String createActivationKey(User user) {
		return user.getPassword().substring(0, 5);
	}

	private void populateEditForm(Model uiModel, SignUpForm form) {
		uiModel.addAttribute("form", form);
		uiModel.addAttribute("genders", Arrays.asList(Gender.values()));
		uiModel.addAttribute("studentstatuses", Arrays.asList(StudentStatus.values()));
		addDateTimeFormatPatterns(uiModel);
	}
	
	void addDateTimeFormatPatterns(Model uiModel) {
		uiModel.addAttribute("student_dateofbirth_date_format", DateTimeFormat.patternForStyle("M-", LocaleContextHolder.getLocale()));
	}

//
//	public void setAccountAutoEnabled(boolean isAccountAutoEnabled) {
//		this.isAccountAutoEnabled = isAccountAutoEnabled;
//	}
}
